#!/bin/bash
# https://www.sonarsource.com/products/sonarqube/downloads/lts/
# [https://docs.sonarsource.com/sonarqube/9.9/requirements/prerequisites-and-overview/](https://docs.sonarsource.com/sonarqube/9.9/requirements/prerequisites-and-overview/)

# 1. you have to config java env.
# 2. you need init database first,example:
#      create database sonarqube;
#      create user sonarqube_dbuser with password '12345678';
#      alter database sonarqube owner to sonarqube_dbuser;


set -euo pipefail

#****** vars ******#
SQ_VERSION="9.9.6.92038"
SQ_USER="sonarqube"
SQ_INSTALL_PATH="/usr/local"

SQ_DB_HOST="10.0.0.28"
SQ_DB_PORT="5432"
SQ_DB_USER="sonarqube_dbuser"
SQ_DB_PASS="12345678"

JAVA_PATH="/usr/local/jdk/bin/java"

color() {
    local message="$1"
    local status="$2"
    local terminal_width
    terminal_width=$(tput cols)
    local middle_column=$(( terminal_width / 2))
    local SETCOLOR_SUCCESS="\033[1;32m"  # 绿色
    local SETCOLOR_FAILURE="\033[1;31m"  # 红色
    local SETCOLOR_WARNING="\033[1;33m"  # 黄色
    local SETCOLOR_NORMAL="\033[0m"      # 重置颜色
    printf '%s\n\033[%sG' "${message}"  "${middle_column}"
    # Print the status message
    printf "["
    case ${status} in
        success|0)
            echo -en  "${SETCOLOR_SUCCESS}  OK  "
            ;;
        failure|1)
            echo -en  "${SETCOLOR_FAILURE}FAILED"
            ;;
        *)
            echo -en "${SETCOLOR_WARNING}WARNING"
            ;;
    esac
    echo -e "${SETCOLOR_NORMAL}]"
}

judge_current_user () {
    if [ "$(id -u)" = "0" ];then
        color "current user is administrator" 0
    else
        color "current user is not administrator" 1
        exit
    fi
}

judge_java_aviliable () {
    if $JAVA_PATH --version | grep 'java 17';then
        color "检测到java版本为17，环境可用" 0
    else
        color "java环境不存在或版本不为17版本." 1
        exit
    fi
}

create_user () {
    if ! id "$1" &> /dev/null;then
        useradd -r -M -s /sbin/nologin "$1" \
        && color "$1 user is created." 0 \
        || { color "$1 user create failed.";exit; }
    else
        color "$1 user is existed." 2
    fi
}

create_dir () {
    local i
    for i in "$@";do
        if [ ! -d "$i" ];then
            mkdir -pv "$i" && color "$i dir is created" 0
        else
            color "$i dir is existed." 2
        fi
    done
}

process_sq_file () {
    create_dir $SQ_INSTALL_PATH
    if ! [ -e "sonarqube-${SQ_VERSION}.zip" ];then
        color "current dir don't exist sonarqube-${SQ_VERSION}.zip" 1
        exit
    fi

    # find uncompress command.
    if command -v unzip &> /dev/null;then
        color "unzip command is exist." 0
        UNCOMPRESS_COMMAND="unzip"
    else
        if command -v jar &> /dev/null;then
            color "jar command is exist." 0
            UNCOMPRESS_COMMAND="jar -xvf"
        else
            if [ -x "${JAVA_PATH%/*}/jar" ];then
                color "${JAVA_PATH%/*}/jar command is exist" 0
                UNCOMPRESS_COMMAND="${JAVA_PATH%/*}/jar -xvf"
            else
                color "can't find uncompress command." 1
                exit
            fi
        fi
    fi

    $UNCOMPRESS_COMMAND "sonarqube-${SQ_VERSION}.zip"
    mv sonarqube-${SQ_VERSION} $SQ_INSTALL_PATH
    chown -R  ${SQ_USER}:${SQ_USER}   ${SQ_INSTALL_PATH}/sonarqube-${SQ_VERSION}
    ln -nfs ${SQ_INSTALL_PATH}/sonarqube-${SQ_VERSION} ${SQ_INSTALL_PATH}/sonarqube
    chmod +x ${SQ_INSTALL_PATH}/sonarqube/bin/linux-x86-64/sonar.sh ${SQ_INSTALL_PATH}/sonarqube/elasticsearch/bin/elasticsearch
}

config_system () {
    sysctl -a | awk '/fs.file-max =/{if($3 < 131072){print "fs.file-max = 131072"}}' >> /etc/sysctl.conf
    sysctl -a | awk '/vm.max_map_count =/{if($3 < 524288){print "vm.max_map_count = 524288"}}' >> /etc/sysctl.conf
    sysctl -p
}

config_service () {
    local SQ_CONFIG_FILE="${SQ_INSTALL_PATH}/sonarqube/conf/sonar.properties"

    if grep -q '^sonar.jdbc.url' $SQ_CONFIG_FILE;then
        sed -i "/^sonar.jdbc.url/c sonar.jdbc.url=jdbc:postgresql://${SQ_DB_HOST}:${SQ_DB_PORT}/sonarqube" $SQ_CONFIG_FILE
    else
        echo "sonar.jdbc.url=jdbc:postgresql://${SQ_DB_HOST}:${SQ_DB_PORT}/sonarqube" >> $SQ_CONFIG_FILE
    fi

    if grep -q '^sonar.jdbc.username' $SQ_CONFIG_FILE;then
        sed -i "/^sonar.jdbc.username/c sonar.jdbc.username=${SQ_DB_USER}" $SQ_CONFIG_FILE
    else
        echo "sonar.jdbc.username=${SQ_DB_USER}" >> $SQ_CONFIG_FILE
    fi

    if grep -q '^sonar.jdbc.password' $SQ_CONFIG_FILE;then
        sed -i "/^sonar.jdbc.password/c sonar.jdbc.password=${SQ_DB_PASS}" $SQ_CONFIG_FILE
    else
        echo "sonar.jdbc.password=${SQ_DB_PASS}" >> $SQ_CONFIG_FILE
    fi

    cat > /lib/systemd/system/sonarqube.service<<EOF
[Unit]
Description=SonarQube service
After=syslog.target network.target

[Service]
Type=simple
User=${SQ_USER}
Group=${SQ_USER}
PermissionsStartOnly=true
ExecStart=/bin/nohup ${JAVA_PATH} -Xms32m -Xmx32m -Djava.net.preferIPv4Stack=true -jar ${SQ_INSTALL_PATH}/sonarqube/lib/sonar-application-9.9.6.92038.jar
StandardOutput=journal
LimitNOFILE=131072
LimitNPROC=8192
TimeoutStartSec=5
Restart=always
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target
EOF
    systemctl daemon-reload
    systemctl enable sonarqube.service
    systemctl start sonarqube.service \
    && color "sonarqube.service start sucess!" 0 \
    || { color "sonarqube.service  start fail." 1; exit; }
}

main () {
    judge_current_user
    judge_java_aviliable
    create_user $SQ_USER
    process_sq_file
    config_system
    config_service
}

main
